package cmd

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	config "code.alibaba-inc.com/agit/quarantine-helper/config"
	"github.com/stretchr/testify/assert"
)

func TestScan(t *testing.T) {
	var (
		assert = assert.New(t)
	)
	type testCase struct {
		quarantinePath string
		commits        map[string]bool
	}

	testCases := []testCase{
		testCase{
			quarantinePath: "../objects/incoming-2DtgUo.0030-increment-unpacked",
			commits: map[string]bool{
				"8756375e8edf693e0c47373b577cc8269db5e4ef": true,
				"a07debcb2673a58d86d130d89de782cd20a1e520": true,
				"499f73c2bae1733380b245091ae350768e62f8ef": true,
			},
		},
		testCase{
			quarantinePath: "../objects/incoming-KD8eHC.0000-initial-unpacked",
			commits: map[string]bool{
				"fad075d2d4fd059d4faa9952489364b5b465bd37": true,
				"22e21a1b8420547a86d39e00afb0027a7468dcad": true,
			},
		},
		testCase{
			quarantinePath: "../objects/incoming-qHG0pD.0010-initial-packfile",
			commits: map[string]bool{
				"fad075d2d4fd059d4faa9952489364b5b465bd37": true,
				"22e21a1b8420547a86d39e00afb0027a7468dcad": true,
			},
		},
		testCase{
			quarantinePath: "../objects/incoming-uxryzY.0020-increment-packfile",
			commits: map[string]bool{
				"499f73c2bae1733380b245091ae350768e62f8ef": true,
				"a07debcb2673a58d86d130d89de782cd20a1e520": true,
				"8756375e8edf693e0c47373b577cc8269db5e4ef": true,
			},
		},
		testCase{
			quarantinePath: "../objects/incoming-empty",
			commits:        map[string]bool{},
		},
		testCase{
			quarantinePath: "../objects/incoming-mixed",
			commits: map[string]bool{
				"fad075d2d4fd059d4faa9952489364b5b465bd37": true,
				"22e21a1b8420547a86d39e00afb0027a7468dcad": true,
				"499f73c2bae1733380b245091ae350768e62f8ef": true,
				"a07debcb2673a58d86d130d89de782cd20a1e520": true,
				"8756375e8edf693e0c47373b577cc8269db5e4ef": true,
			},
		},
	}

	var (
		err       error
		rawOutput []byte
	)

	for _, testCase := range testCases {
		config.Quarantine, err = filepath.Abs(testCase.quarantinePath)
		assert.Nil(err)
		stdout := os.Stdout
		reader, writer, _ := os.Pipe()
		os.Stdout = writer
		err = scan()
		assert.Nil(err)
		writer.Close()
		rawOutput, err = ioutil.ReadAll(reader)
		if len(rawOutput) == 0 {
			assert.Equal(len(testCase.commits), 0)
			os.Stdout = stdout
			continue
		}
		output := strings.TrimSuffix(string(rawOutput), "\n")
		os.Stdout = stdout
		commits := strings.Split(output, "\n")
		assert.Equal(len(testCase.commits), len(commits))
		for _, commit := range commits {
			_, ok := testCase.commits[commit]
			assert.True(ok)
		}
	}
}
